package com.tsc.common.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chentl
 * @Date: 2025/08/15/22:41
 * @Description: 统一响应体基类
 */
@Data
@Accessors(chain = true)     // 支持链式调用
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResponse<T> implements Serializable {
    // 状态码
    private int code;
    // 消息
    private String msg;
    // 响应数据
    private T data;
    // 请求路径
    private String path;
    // 时间戳
    private long timestamp = System.currentTimeMillis();
    // 追踪ID（用于日志追踪）
    private String traceId;

    /**
     * 成功响应（无数据）
     */
    public static <T> ApiResponse<T> success() {
        return new ApiResponse<T>()
                .setCode(ResponseCode.SUCCESS.getCode())
                .setMsg(ResponseCode.SUCCESS.getMessage());
    }

    /**
     * 成功响应（带数据）
     */
    public static <T> ApiResponse<T> success(T data) {
        return (ApiResponse<T>) success().setData(data);
    }

    /**
     * 失败响应（使用状态码枚举）
     */
    public static <T> ApiResponse<T> fail(ResponseCode responseCode) {
        return new ApiResponse<T>()
                .setCode(responseCode.getCode())
                .setMsg(responseCode.getMessage());
    }

    /**
     * 失败响应（自定义消息）
     */
    public static <T> ApiResponse<T> fail(int code, String msg) {
        return new ApiResponse<T>().setCode(code).setMsg(msg);
    }

    /**
     * 失败响应（自定义消息、数据）
     */
    public static <T> ApiResponse<T> fail(int code, String msg, T data) {
        return new ApiResponse<T>()
               .setCode(code)
               .setMsg(msg)
               .setData(data);
    }

    /**
     * 业务异常响应
     */
    public static <T> ApiResponse<T> businessError(String msg) {
        return fail(ResponseCode.BUSINESS_ERROR.getCode(), msg);
    }

    /**
     * 设置请求路径（内部使用）
     */
    ApiResponse<T> withPath(String path) {
        return this.setPath(path);
    }

    /**
     * 设置追踪ID（内部使用）
     */
    ApiResponse<T> withTraceId(String traceId) {
        return this.setTraceId(traceId);
    }
}
